package com.mall.b2c.plugin.payment.alipay;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;

import net.sf.json.JSONObject;

import com.mall.b2c.domain.member.MemberDomain;
import com.mall.b2c.domain.order.OrderDomain;
import com.mall.b2c.plugin.payment.AbstractPaymentPlugin;
import com.mall.b2c.plugin.payment.IPaymentEvent;
import com.mall.b2c.plugin.payment.alipay.config.AlipayConfig;
import com.mall.b2c.plugin.payment.alipay.util.AlipayNotify;
import com.mall.b2c.plugin.payment.alipay.util.AlipaySubmit;
import com.mall.b2c.util.SerialNumberUtil;
import com.mall.b2c.util.SettingUtils;
import com.mall.common.domain.component.ComponentDomain;
import com.mall.common.domain.component.PaymentLogDomain;
import com.mall.common.exception.NoticeException;
import com.mall.common.util.DateHelper;


/**
 * 支付宝即时到账插件 
 *
 */
public class AlipayDirectPlugin extends AbstractPaymentPlugin implements IPaymentEvent {

	@SuppressWarnings("unchecked")
	@Override
	public String onPay(ComponentDomain component, OrderDomain order,
			String bankInfo, String pickupUrl, String receiveUrl)
			throws Exception {
		JSONObject jsonObject = component.getConfigJson("payConfig");
		Map<String, String> params = (Map<String, String>) JSONObject.toBean(jsonObject, Map.class);

		BigDecimal totalCost = order.getCash();
		order.setTradeNo(SerialNumberUtil.buildTradeNo());

		params.put("_input_charset", AlipayConfig.input_charset);
		params.put("partner", AlipayConfig.partner);
		params.put("notify_url", receiveUrl);
		params.put("return_url", pickupUrl);
        params.put("total_fee", totalCost.setScale(2).toString());
        params.put("anti_phishing_key", AlipaySubmit.query_timestamp());
        params.put("out_trade_no", order.getTradeNo());
        params.put("subject", SettingUtils.get().getName() + "订单");

        return AlipaySubmit.buildRequest(params, "get", "确定");
	}

	@Override
	public String onReturn(Long memberId, Map<String, String> params)
			throws Exception {
		String trade_no = params.get("trade_no");
		String out_trade_no = params.get("out_trade_no");
		List<PaymentLogDomain> logs = paymentLogService.getList("dealId", trade_no);

		JSONObject result = new JSONObject();
		result.put("orderNo", trade_no);
		for(PaymentLogDomain log : logs){
			if(out_trade_no.equals(log.getTradeNo())){
				if(log.getPaySuccess() == null || !log.getPaySuccess()){
					result.put("isSuccess", false);
					result.put("result", "fail");
					return result.toString();
				}else{
					result.put("isSuccess", true);
					result.put("result", "success");
					return result.toString();
				}
			}
		}
		String total_fee = params.get("total_fee");
		BigDecimal amount = new BigDecimal(0);
		if(!StringUtils.isEmpty(total_fee)){
			amount = new BigDecimal(total_fee);
		}

		if(memberId == null){
			result.put("isSuccess", false);
			result.put("result", "fail");
			return result.toString();
		}
		MemberDomain member = memberService.find(memberId);
		if(member == null){
			result.put("isSuccess", false);
			result.put("result", "fail");
			return result.toString();
		}
		
		String notify_time = params.get("notify_time");
		
		ComponentDomain component = componentService.get("componentId", getId());
		
		PaymentLogDomain paymentLog = new PaymentLogDomain();
		paymentLog.setOrderAccount(amount);
		paymentLog.setTradeNo(out_trade_no);
		paymentLog.setMemberName(member.getUsername());
		paymentLog.setPayType(component.getPaymemtType());
		paymentLog.setDealId(trade_no);
		paymentLog.setDealTime(DateHelper.string2Date(notify_time, "yyyy-MM-dd HH:mm:ss"));
		paymentLog.setPayAmount(amount);
		paymentLogService.persist(paymentLog);//保存支付记录
		
		String trade_status = params.get("trade_status");
		if(AlipayNotify.verify(params)){//验证成功
			if("TRADE_FINISHED".equals(trade_status) 
					|| "TRADE_SUCCESS".equals(trade_status)){
				boolean isSuccess = memberService.recharge(out_trade_no, component.getPaymemtType(), amount, trade_no, memberId);
				paymentLog.setPaySuccess(isSuccess);
				paymentLogService.update(paymentLog);//保存支付记录
				if(isSuccess && !isRecharge(out_trade_no)){
					try {
						orderService.pay(out_trade_no, component.getPaymemtType(), trade_no);
						paymentLog.setPaySuccess(true);
						paymentLogService.update(paymentLog);//保存支付记录
					} catch (NoticeException e) {
						paymentLog.setPaySuccess(false);
						paymentLog.setErrorCode(e.getMessage());
						paymentLogService.update(paymentLog);//保存支付记录
					}
				}
			}
			result.put("isSuccess", true);
			result.put("result", "success");
			return result.toString();
		}else{//验证失败
			paymentLog.setPaySuccess(false);
			paymentLog.setErrorCode("验证失败");
			paymentLogService.update(paymentLog);
			result.put("isSuccess", false);
			result.put("result", "fail");
			return result.toString();
		}
	}
	
	@Override
	public void register() {
		
	}
	
	@Override
	public String getAuthor() {
		return "fangchen";
	}

	@Override
	public String getId() {
		return "alipayDirectPlugin";
	}

	@Override
	public String getName() {
		return "支付宝即时到帐接口";
	}

	@Override
	public String getType() {
		return "payment";
	}

	@Override
	public String getVersion() {
		return "1.0";
	}

	@Override
	public void perform(Object... params) {
		
	}

	@Override
	public String getTradeNo(Map<String, String> params) throws Exception {
		return params.get("out_trade_no");
	}


}
